package hkr.vfu.bluecenter.swipe_fragments;


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Timer;

import hkr.vfu.bluecenter.BluecenterController;
import hkr.vfu.bluecenter.R;
import hkr.vfu.bluecenter.activities.SensorSettingsActivity;
import hkr.vfu.bluecenter.activities.SettingsActivity;
import hkr.vfu.bluecenter.backend.BluetoothManager;
import hkr.vfu.bluecenter.backend.BluetoothSingleton;
import hkr.vfu.bluecenter.backend.BoxVO;
import hkr.vfu.bluecenter.backend.ContinuousTimerTask;
import hkr.vfu.bluecenter.backend.DataSingleton;
import hkr.vfu.bluecenter.backend.LogHandler;
import hkr.vfu.bluecenter.backend.SensorVO;

/**
 * Created by mattiasbowallius on 31/10/13.
 */
public class BoxFragment extends ListFragment implements BluecenterFragment, Button.OnClickListener {


    private static final String ARG_SECTION_NUMBER = "section_number";
    private static final int FINISHED_SENSORSETTINGS_ACTIVITY = 1;
    public File repetitiveContinuousFile;
    private List<SensorVO> vos;
    private DataSingleton dataSingleton;
    private BluetoothSingleton bluetoothSingleton;
    private File runButtonScriptFile;
    private SensorListAdapter adapter;
    private boolean runContinuosly = false;
    private Timer timer;
    private ImageButton continuousSampleButton;
    private BluecenterController bluecenterController;
    private ContinuousTimerTask timerTask;
    private File initContinuousFile;
    private File endContinuousFile;
    private String boxMac;


    /**
     * Returns a new instance of this fragment for the given section
     * number.
     */
    public static BoxFragment newInstance(String boxMac, int position) {
        BoxFragment fragment = new BoxFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, position);
        args.putString("MAC", boxMac);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        boxMac = getArguments().getString("MAC");
        bluetoothSingleton = BluetoothSingleton.getInstance();
        return inflater.inflate(R.layout.box_fragment, container, false);

    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        Intent settingsIntent = new Intent(bluecenterController, SensorSettingsActivity.class);
        settingsIntent.putExtra("position", position);
        settingsIntent.putExtra("MAC", boxMac);
        startActivityForResult(settingsIntent, FINISHED_SENSORSETTINGS_ACTIVITY);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == FINISHED_SENSORSETTINGS_ACTIVITY) {
            bluecenterController.saveHashMap();
            updateUI();
        }
    }

    @Override
    public void updateUI() {
        if (bluetoothSingleton.isConnected(boxMac)) {
            SensorVO[] sensorVOs = dataSingleton.getBoxWithMAC(boxMac)
                    .getSensors();
            vos.clear();
            Collections.addAll(vos, sensorVOs);
            adapter.setSensorVOs(vos);
            adapter.notifyDataSetChanged();
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        bluecenterController = (BluecenterController) getActivity();
        dataSingleton = DataSingleton.getInstance();
        bluetoothSingleton = BluetoothSingleton.getInstance();
        vos = new ArrayList<SensorVO>();
        runButtonScriptFile = new File(bluecenterController.getFilesDir() + "Run_Button_Script.txt");
        initContinuousFile = new File(bluecenterController.getFilesDir() + "Init_Continuous_Script.txt");
        repetitiveContinuousFile = new File(bluecenterController.getFilesDir() + "Repetitive_Continous_Script.txt");
        endContinuousFile = new File(bluecenterController.getFilesDir() + "End_Continous_Script.txt");

        initializeButtons();

        if (bluetoothSingleton.isConnected(boxMac)) {
            SensorVO[] sensorVOs = dataSingleton.getBoxWithMAC(boxMac)
                    .getSensors();
            vos.clear();
            Collections.addAll(vos, sensorVOs);
        }
        adapter = new SensorListAdapter(bluecenterController, R.layout.sensor_list_layout, vos);
        setListAdapter(adapter);
        bluecenterController.findViewById(R.id.start_data_collection_button)
                .setOnClickListener(this);

    }

    @Override
    public void onStart() {
        super.onStart();
        updateUI();
    }

    @Override
    public void onResume() {
        super.onResume();
        updateUI();
    }


    /**
     * Method for when the start data collection button in the BoxFragment is pressed
     */
    public void runButtonPressed() {
        if (!BluetoothSingleton.getInstance().isConnected(boxMac)) {
            Toast.makeText(bluecenterController, "No Connection", Toast.LENGTH_SHORT).show();
            return;
        }
        executeCommandsFromFile(runButtonScriptFile);
    }

    public void executeCommandsFromFile(File file) {
        try {
            BufferedReader in = new BufferedReader(new FileReader(file));
            StringBuilder builder = new StringBuilder();
            String line;
            while ((line = in.readLine()) != null) {
                builder.append(line).append('\n');
            }
            in.close();
            String commandsString = builder.toString();
            String[] cmds = commandsString.split("\n");
            executeCommand(cmds, cmds.length - 1);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private void initializeButtons() {
        ImageButton runButton = (ImageButton) bluecenterController.findViewById(R.id.start_data_collection_button);
        continuousSampleButton = (ImageButton) bluecenterController.findViewById(R.id.sample_continuously_button);
        ImageButton saveButton = (ImageButton) bluecenterController.findViewById(R.id.save_to_logfile_button);

        runButton.setOnClickListener(this);
        continuousSampleButton.setOnClickListener(this);
        saveButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start_data_collection_button:
                runButtonPressed();
                break;
            case R.id.sample_continuously_button:
                continuosSampleButtonPressed();
                break;
            case R.id.save_to_logfile_button:
                saveLogFile();
                break;
        }
    }

    private void continuosSampleButtonPressed() {
        if (!BluetoothSingleton.getInstance().isConnected(boxMac)) {
            Toast.makeText(bluecenterController, "No Connection", Toast.LENGTH_SHORT).show();
            return;
        }
        timer = new Timer();
        if (!runContinuosly) {
            continuousSampleButton.setImageDrawable(getResources().getDrawable(R.drawable.stopbutton));
            executeCommandsFromFile(initContinuousFile);
            timerTask = new ContinuousTimerTask(bluecenterController, this);
            timer.scheduleAtFixedRate(timerTask, 0, 1000);
        } else {
            continuousSampleButton.setImageDrawable(getResources().getDrawable(R.drawable.samplebutton));
            timerTask.cancel();
            executeCommandsFromFile(endContinuousFile);

        }
        runContinuosly = !runContinuosly;
    }

    public boolean executeCommand(String[] commands, int currentIndex) {
        if (currentIndex < 0) {
            return true;
        }
        String command = commands[currentIndex];
        command += '\r';
        if (executeCommand(commands, currentIndex - 1)) {
            BluetoothManager.runCommand(boxMac, command, bluecenterController);
            return true;
        }
        return false;
    }

    public void saveLogFile() {

        if (bluetoothSingleton.isConnected(boxMac)) {
            LogHandler logHandler = new LogHandler();
            BoxVO boxVO = dataSingleton.getBoxWithMAC(boxMac);
            File root = Environment.getExternalStorageDirectory();
            logHandler.sendToFile(root, boxVO);

        } else {
            Toast.makeText(bluecenterController, "No Connection", Toast.LENGTH_SHORT).show();
        }
    }

    public String returnSensorValue(SensorVO sensorVO) {
        double sensorValue = sensorVO.getK() * sensorVO.getValue() + sensorVO.getM();
        return "" + sensorValue;
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.bluecenter_controller, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_settings:
                Intent settingsIntent = new Intent(bluecenterController, SettingsActivity.class);
                settingsIntent.putExtra("MAC", boxMac);
                startActivityForResult(settingsIntent, FINISHED_SENSORSETTINGS_ACTIVITY);
                return true;
            case R.id.disconnect_action:
                bluetoothSingleton.stopSocket(boxMac);
                bluecenterController.removeBoxFragment(getArguments().getInt(ARG_SECTION_NUMBER));
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    public String getMac() {
        return boxMac;
    }

    private class SensorListAdapter extends ArrayAdapter<SensorVO> {

        private List<SensorVO> sensorVOs;
        private int textViewResourceId;
        private Context context;

        public SensorListAdapter(Context context, int textViewResourceId, List<SensorVO> objects) {
            super(context, textViewResourceId, objects);
            sensorVOs = objects;
            this.textViewResourceId = textViewResourceId;
            this.context = context;
        }

        public void setSensorVOs(List<SensorVO> vos) {
            sensorVOs = vos;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            // object item based on the position
            SensorVO sensorVO = sensorVOs.get(position);
            String sensorName = "" + sensorVO.getSensorName();
            if (sensorName.equals("Channel")) {
                sensorVO.setSensorName(sensorVO.getSensorName() + " " + position);
            }

            if (convertView == null) {
                // inflate the layout
                LayoutInflater inflater = ((Activity) context).getLayoutInflater();
                convertView = inflater.inflate(textViewResourceId, parent, false);
            }

            // get the TextView and then set the text (item name) and tag (item ID) values
            ImageView image = (ImageView) convertView.findViewById(R.id.icon);
            TextView valueLine = (TextView) convertView.findViewById(R.id.sensor_value);
            TextView nameLine = (TextView) convertView.findViewById(R.id.sensor_name);
            TextView valueUnitLine = (TextView) convertView.findViewById(R.id.sensor_unit);
            switch (sensorVO.getType()) {
                case SensorVO.ANALOG_TYPE:
                    image.setImageDrawable(getResources().getDrawable(R.drawable.thermometer_big));
                    break;
                case SensorVO.PULSE_TYPE:
                    image.setImageDrawable(getResources().getDrawable(R.drawable.rotation_image));
                    break;
            }

            double value = Double.parseDouble(returnSensorValue(sensorVO));
            String stringValue = String.format("%.1f", value);

            valueLine.setText(stringValue);
            nameLine.setText(sensorVO.getSensorName());
            valueUnitLine.setText(sensorVO.getUnitString());

            return convertView;

        }
    }
}
